﻿using fuzhu;
using LH.Model.APAR;
using LH.Model.PU;
using LH.Models.APAR;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using MimeKit;
using Org.BouncyCastle.Crypto;
using SqlSuarEntity;
using SqlSugar;
using U8COWeb;
using XXX.Bo;
using XXX.Common;
using XXX.Models;
using ZDEntity;

namespace Yonyou.U8.BO
{
    //应付款单
    public class APVouchVM : AP_Vouch
    {
        //当前的数据库连接字符串
        public string conStr { get; set; }
        public static string cDatabase = ""; 
        public string xmlConfig { get; set; }

        public APVouchVM(Head head, List<Body> bodies) : base(head, bodies)
        {
            //conStr
            conStr = CanShu.conStr;
            //初始化定义xmlconfig
            xmlConfig = XmlOperation.GetConfigXML();
        }
        
        public RetModel2 Add()
        {
            try
            {
                string idcheck = "";
                if (Exists(ref idcheck))
                {
                    return DBService.ReErrObject($"当前委外发票号{head.cVouchID}已存在");
                }
                foreach (Body body in bodies)
                {
                    body.editprop = "A";
                }


                //直接赋值了审核人，所以不需要再审核了
                string xmlconfig = XmlOperation.GetConfigXMLDate(head.dVouchDate);
                if (!APVouchDALCO.AddAPVouch(this, xmlConfig, out string err, out string id, out string ccode))
                {
                    //这个提示也认为是成功的
                    if (err == "add 下标越界")
                    {
                        return DBService.ReOKObject(ccode);
                    }
                    else
                    {
                        return DBService.ReErrObject("新增失败：" + err);
                    }
                }

                return DBService.ReOKObject(ccode);
                //}
            }
            catch (Exception ex)
            {
                return DBService.ReErrObject(ex.Message);
            }



        }
        /// <summary>
        /// 采购订单 弃审并删除
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public RetModel2 Delete()
        {
            try
            {
                string ID = "";
                if (!Exists(ref ID))
                {
                    return DBService.ReOKObject("当前单据号不存在");
                }
                string xmlconfig = XmlOperation.GetConfigXMLDate(head.dVouchDate);
                if (!APVouchDALCO.OperationAPVouch(ID, xmlConfig, "delete", out string err))
                {
                    return DBService.ReErrObject("删除失败：" + err);
                }

                return DBService.ReOKObject(head.cVouchID + "删除完成");
                //}
            }
            catch (Exception ex)
            {
                return DBService.ReErrObject(ex.Message);
            }
        }

        /// <summary>
        /// 传入json转换成PurchaseOrderVM
        /// </summary>
        /// <param name="json"></param>
        /// <param name="cErr"></param>
        /// <returns></returns>
        public APVouchVM GetAddEntity(Api_APVouch obj, ref string cErr, ref string cVouchID)
        {

            try
            {

                if (string.IsNullOrWhiteSpace(obj.cVouchID))
                {
                    cErr = "委外发票号不能为空";
                    return null;
                }
                cVouchID = obj.cVouchID;
                if (string.IsNullOrWhiteSpace(obj.cMaker))
                {
                    cErr = "制单人不能为空";
                    return null;
                }
                if (string.IsNullOrWhiteSpace(obj.cDwCode))
                {
                    cErr = "供应商不能为空";
                    return null;
                }
                string idcheck = "";
                if (Exists(ref idcheck))
                {
                    cErr = $"单据号{obj.cVouchID}已存在";
                    return null;
                }
                //账套是001的，本币是港币HKD

                //string sql = string.Format("select cexch_name from foreigncurrency where iotherused=-1");
                //string benbi = DbHelper.GetDbString(DbHelper2.ExecuteScalar(sql, conStr));

                string benbi = "人民币"; 
                GLaccvouchVM gLaccvouchVM = new GLaccvouchVM();
                gLaccvouchVM.conStr = conStr;
                LH.Model.APAR.AP_Vouch.Head rdHead = new LH.Model.APAR.AP_Vouch.Head();

                rdHead.cVouchType = "P0";//单据类型
                rdHead.cFlag = "AP";
                rdHead.dVouchDate = DbHelper.GetDbDate(obj.dVouchDate).ToString("yyyy-MM-dd");


                rdHead.cDwCode = obj.cDwCode;
                //rdHead.iPeriod = DbHelper.GetDbDate(dVouchDate).Month.ToString();
                //科目辅助核算判断
                int b_dep_fzhs = 0;
                int b_person_fzhs = 0;
                int b_cus_fzhs = 0;
                int b_vendor_fzhs = 0;
                int b_fitem_fzhs = 0;
                string c_cass_item = "";
                string c_cexch_name = "";  //凭证币种
                int b_bend = 0;
                int b_bclose = 0;
                int b_bcDefine1 = 0;
                int b_bcDefine2 = 0;
                int b_bcDefine3 = 0;
                int b_bcDefine4 = 0;
                int b_bcDefine5 = 0;
                int b_bcDefine6 = 0;
                int b_bcDefine7 = 0;
                int b_bcDefine8 = 0;
                int b_bcDefine9 = 0;
                int b_bcDefine10 = 0;
                int b_bcDefine11 = 0;
                int b_bcDefine12 = 0;
                int b_bcDefine13 = 0;
                int b_bcDefine14 = 0;
                int b_bcDefine15 = 0;
                int b_bcDefine16 = 0;
                string c_cother = "";
                if (!string.IsNullOrWhiteSpace(obj.cCode))
                {
                    //if (!gLaccvouchVM.exist_code(cCode, DbHelper.GetDbDate(dVouchDate).Year, ref errMsg))
                    //{
                    //    throw new Exception(errMsg);
                    //} 
                    bool b3 = gLaccvouchVM.getFuZhuHeSuan(obj.cCode, DbHelper.GetDbDate(obj.dVouchDate).Year, ref b_dep_fzhs, ref b_person_fzhs, ref b_cus_fzhs,
                                  ref b_vendor_fzhs, ref b_fitem_fzhs, ref c_cass_item, ref c_cexch_name, ref b_bend, ref b_bclose, ref b_bcDefine1,
                                  ref b_bcDefine2, ref b_bcDefine3, ref b_bcDefine4, ref b_bcDefine5, ref b_bcDefine6, ref b_bcDefine7,
                                  ref b_bcDefine8, ref b_bcDefine9, ref b_bcDefine10, ref b_bcDefine11, ref b_bcDefine12, ref b_bcDefine13,
                                  ref b_bcDefine14, ref b_bcDefine15, ref b_bcDefine16, ref c_cother, ref cErr);

                    if (!b3)
                    {
                        throw new Exception(cErr);
                    }

                    rdHead.cCode = obj.cCode;
                    if (string.IsNullOrEmpty(c_cother) || c_cother != "AP")
                    {
                        throw new Exception("表头科目不是应付受控科目，不能录入：" + rdHead.cCode);
                    }
                    //如果币种有外币核算，这边输入的不一样进行提示
                    if (c_cexch_name != "" && obj.cexch_name != c_cexch_name)
                    {
                        throw new Exception("表头科目" + rdHead.cCode + "有外币核算，请输入外币:" + c_cexch_name);
                    }


                    //没有外币核算，输入的币种必须和本币一致
                    if (c_cexch_name == "" && obj.cexch_name != benbi)
                    {
                        throw new Exception("科目" + rdHead.cCode + "没有外币核算，请输入本位币币:" + benbi);
                    }
                }
                rdHead.cexch_name = obj.cexch_name;
                if (string.IsNullOrEmpty(obj.cexch_name))
                {
                    throw new Exception("表头币种不能为空");
                }
                 

                rdHead.iAmount_f = obj.iAmount_f;
                if (string.IsNullOrEmpty(obj.iAmount) || obj.iAmount == "0")
                {
                    throw new Exception("表头金额不能为空");
                }
                if (string.IsNullOrEmpty(obj.iAmount_f) || obj.iAmount_f == "0")
                {
                    throw new Exception("表头外币金额不能为空");
                }
                //如果没有外币核算，汇率输入不是1，或者外币金额不等于本币金额，提示输入错误
                //if (c_cexch_name == "" && (iExchRate != "1" || iAmount!= iAmount_f))
                //{
                //    throw new Exception("表头外币金额不等于本币金额");
                //}
                //如果有外币核算，汇率反算
                if (c_cexch_name != "")
                {
                    rdHead.iExchRate = DbHelper.GetDbString(DbHelper.GetDbdecimal(obj.iAmount) / DbHelper.GetDbdecimal(obj.iAmount_f));
                }
                else
                {
                    rdHead.iExchRate = "1";
                }
                rdHead.iAmount = obj.iAmount;
                rdHead.iRAmount_f = obj.iAmount_f;
                rdHead.iRAmount = obj.iAmount;
                rdHead.cTypeName = "其他应付单";
                //rdHead.cCheckMan = "demo";
                rdHead.cOperator = obj.cMaker;
                rdHead.cVouchID = obj.cVouchID;
                rdHead.VT_ID = "8056";
                //rdHead.cLink = "P00000000018";
                rdHead.bStartFlag = "False";
                rdHead.cDigest = obj.cDigest;
                rdHead.iMoney = obj.iAmount;
                rdHead.iOriMoney = obj.iAmount_f;
                rdHead.iDiscountTaxType = "1";
                rdHead.bd_c = "False";
                rdHead.bCredit = "0";

                //不管有没有辅助核算，单据都进行赋值
                if (b_vendor_fzhs == 1)
                {
                    if (string.IsNullOrWhiteSpace(obj.cDwCode))
                    {
                        throw new Exception("表头有供应商核算，表头供应商不能为空");
                    }


                }
                //判断单位是否存在
                if (!string.IsNullOrEmpty(obj.cDwCode) && !gLaccvouchVM.exist_vendor(obj.cDwCode, ref cErr))
                {
                    throw new Exception(cErr);
                }
                rdHead.cDwCode = obj.cDwCode;

                //有部门核算，没有输入，进行提示
                if (b_dep_fzhs == 1)
                {
                    if (string.IsNullOrWhiteSpace(obj.cDeptCode))
                    {
                        throw new Exception("表头有部门核算，部门不能为空");
                    }
                }
                //检查部门输入是否正确
                if (!string.IsNullOrEmpty(obj.cDeptCode) && !gLaccvouchVM.exist_dept(obj.cDeptCode, ref cErr))
                {
                    throw new Exception(cErr);
                }
                rdHead.cDeptCode = obj.cDeptCode;
                //有人员核算，没有输入，进行提示
                if (b_person_fzhs == 1)
                {
                    if (string.IsNullOrWhiteSpace(obj.cPerson))
                    {
                        throw new Exception("表头有人员核算，业务员不能为空");
                    }

                }
                if (!string.IsNullOrEmpty(obj.cPerson) && !gLaccvouchVM.exist_person(obj.cPerson, ref cErr))
                {
                    throw new Exception(cErr);
                }
                rdHead.cPerson = obj.cPerson;
                //有项目核算，没有输入，进行提示
                if (b_fitem_fzhs == 1)
                {
                    if (string.IsNullOrWhiteSpace(obj.cItemCode))
                    {
                        throw new Exception("表头有项目核算，表头项目不能为空");
                    }
                    //没有检查项目是否正确

                }
                rdHead.cItem_Class = obj.cItem_Class;
                rdHead.cItemCode = obj.cItemCode;

                rdHead.editprop = "A";
                rdHead.iAmount_s = "0";
                rdHead.iRAmount_s = "0";

                List<LH.Model.APAR.AP_Vouch.Body> bodies = new List<LH.Model.APAR.AP_Vouch.Body>();

                decimal totalItemAmount = 0;
                for (int i = 0; i < obj.itemList.Count; i++)
                {
                    LH.Model.APAR.AP_Vouch.Body body = new LH.Model.APAR.AP_Vouch.Body();




                    if (!string.IsNullOrWhiteSpace(obj.itemList[i].cCode))
                    {
                        b_dep_fzhs = 0;
                        b_person_fzhs = 0;
                        b_cus_fzhs = 0;
                        b_vendor_fzhs = 0;
                        b_fitem_fzhs = 0;
                        c_cass_item = "";
                        c_cexch_name = "";  //凭证币种
                        b_bend = 0;
                        b_bclose = 0;
                        b_bcDefine1 = 0;
                        b_bcDefine2 = 0;
                        b_bcDefine3 = 0;
                        b_bcDefine4 = 0;
                        b_bcDefine5 = 0;
                        b_bcDefine6 = 0;
                        b_bcDefine7 = 0;
                        b_bcDefine8 = 0;
                        b_bcDefine9 = 0;
                        b_bcDefine10 = 0;
                        b_bcDefine11 = 0;
                        b_bcDefine12 = 0;
                        b_bcDefine13 = 0;
                        b_bcDefine14 = 0;
                        b_bcDefine15 = 0;
                        b_bcDefine16 = 0;
                        c_cother = "";

                        bool b1 = gLaccvouchVM.getFuZhuHeSuan(obj.itemList[i].cCode, DbHelper.GetDbDate(obj.dVouchDate).Year, ref b_dep_fzhs, ref b_person_fzhs, ref b_cus_fzhs,
                                 ref b_vendor_fzhs, ref b_fitem_fzhs, ref c_cass_item, ref c_cexch_name, ref b_bend, ref b_bclose, ref b_bcDefine1,
                                 ref b_bcDefine2, ref b_bcDefine3, ref b_bcDefine4, ref b_bcDefine5, ref b_bcDefine6, ref b_bcDefine7,
                                 ref b_bcDefine8, ref b_bcDefine9, ref b_bcDefine10, ref b_bcDefine11, ref b_bcDefine12, ref b_bcDefine13,
                                 ref b_bcDefine14, ref b_bcDefine15, ref b_bcDefine16, ref c_cother, ref cErr);
                        if (!b1)
                        {
                            throw new Exception(cErr );
                        }

                        body.cCode = obj.itemList[i].cCode;
                        if (!string.IsNullOrEmpty(c_cother) && c_cother == "AP")
                        {
                            throw new Exception("表体科目不能录入应付受控科目：" + body.cCode);
                        }

                        //如果币种有外币核算，这边输入的不一样进行提示
                        if (c_cexch_name != "" && body.cexch_name != c_cexch_name)
                        {
                            throw new Exception("表体科目" + body.cCode + "有外币核算，请输入外币:" + c_cexch_name);
                        }


                        //没有外币核算，输入的币种必须和本币一致
                        if (c_cexch_name == "" && body.cexch_name != benbi)
                        {
                            throw new Exception("科目" + body.cCode + "没有外币核算，请输入本位币币:" + benbi);
                        }
                    }
                    body.cDwCode = obj.itemList[i].cDwCode;
                    body.cDeptCode = obj.itemList[i].cDeptCode;
                    body.cPerson = obj.itemList[i].cPerson;
                    body.cItem_Class = obj.itemList[i].cItem_Class;
                    body.cItemCode = obj.itemList[i].cItemCode;
                    //body.iExchRate = itemList[i].iExchRate;
                    body.cexch_name = obj.itemList[i].cexch_name;
                    body.iAmount = obj.itemList[i].iAmount;
                    body.iAmount_f = obj.itemList[i].iAmount_f;
                    if (string.IsNullOrEmpty(obj.itemList[i].cexch_name))
                    {
                        throw new Exception("表体币种不能为空");
                    }
                   
                    //如果有外币核算，汇率没有输入，提示输入汇率
                    if (c_cexch_name != "")
                    {
                        body.iExchRate = DbHelper.GetDbString(DbHelper.GetDbdecimal(body.iAmount) / DbHelper.GetDbdecimal(body.iAmount_f));
                    }
                    else
                    {
                        body.iExchRate = "1";
                    }

                    if (string.IsNullOrEmpty(obj.itemList[i].iAmount) || obj.itemList[i].iAmount == "0")
                    {
                        throw new Exception("明细行金额不能为空");
                    }
                    if (string.IsNullOrEmpty(obj.itemList[i].iAmount_f) || obj.itemList[i].iAmount_f == "0")
                    {
                        throw new Exception("明细行外币金额不能为空");
                    }
                    //如果没有外币核算，汇率输入不是1，或者外币金额不等于本币金额，提示输入错误
                    if (c_cexch_name == "" && (body.iExchRate != "1" || body.iAmount != body.iAmount_f))
                    {
                        throw new Exception("表体外币金额不等于本币金额");
                    }
                    //不管有没有辅助核算，单据都进行赋值
                    if (b_vendor_fzhs == 1)
                    {
                        if (string.IsNullOrWhiteSpace(body.cDwCode))
                        {
                            throw new Exception("表体有供应商核算，表体供应商不能为空");
                        }
                    }
                    //如果不为空，就判断单位是否存在
                    if (!string.IsNullOrEmpty(body.cDwCode) && !gLaccvouchVM.exist_vendor(body.cDwCode, ref cErr))
                    {
                        throw new Exception(cErr);
                    }

                    //有部门核算，没有输入，进行提示
                    if (b_dep_fzhs == 1)
                    {
                        if (string.IsNullOrWhiteSpace(body.cDeptCode))
                        {
                            throw new Exception("表体有部门核算，表体部门不能为空");
                        }

                    }
                    //如果不为空，检查部门输入是否正确
                    if (!string.IsNullOrEmpty(body.cDeptCode) && !gLaccvouchVM.exist_dept(body.cDeptCode, ref cErr))
                    {
                        throw new Exception(cErr);
                    }


                    //有人员核算，没有输入，进行提示
                    if (b_person_fzhs == 1)
                    {
                        if (string.IsNullOrWhiteSpace(body.cPerson))
                        {
                            throw new Exception("表体有人员核算，业务员不能为空");
                        }

                    }
                    if (!string.IsNullOrEmpty(body.cPerson) && !gLaccvouchVM.exist_person(body.cPerson, ref cErr))
                    {
                        throw new Exception(cErr);
                    }
                    //有项目核算，没有输入，进行提示
                    if (b_fitem_fzhs == 1)
                    {
                        if (string.IsNullOrWhiteSpace(body.cItemCode))
                        {
                            throw new Exception("表体有项目核算，表体项目不能为空");
                        }
                        //没有检查项目是否正确

                    }
                    body.cDigest = obj.itemList[i].cDigest;
                    body.bd_c = "True";
                    body.cDirection = "借";
                    body.iAmt_s = "0";
                    body.iNatTax = "0";
                    body.iNoTaxAmount = body.iAmount;
                    body.iNoTaxAmount_f = body.iAmount_f;
                    body.editprop = "A";

                    bodies.Add(body);
                    totalItemAmount += decimal.Parse(body.iAmount);
                }

                if (totalItemAmount != decimal.Parse(obj.iAmount))
                {
                    throw new Exception("表体金额合计值与表头金额不一致");
                }
                 
                APVouchVM model = new APVouchVM(rdHead, bodies);


                return model;

            }
            catch (Exception ex)
            {
                cErr = ex.Message;
                return null;
            }





        }
        /// <summary>
        /// 传入json转换成PurchaseOrderVM
        /// </summary>
        /// <param name="json"></param>
        /// <param name="cErr"></param>
        /// <returns></returns>
        public APVouchVM GetCodeEntity(Api_APVouch obj, ref string cErr)
        {

            try
            {

                AP_Vouch.Head head = new AP_Vouch.Head();
                head.cVouchID = obj.cVouchID;
                //增加读取日期
                using (SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
                {
                    ConnectionString = conStr,
                    DbType = SqlSugar.DbType.SqlServer,
                    IsAutoCloseConnection = true
                }))
                {
                    string sql = string.Format("select dVouchDate from AP_ApVouch where cVouchID='{0}' ", head.cVouchID);
                    var vdate = db.Ado.GetScalar(sql);
                    if (vdate != null)
                    {
                        head.dVouchDate = vdate.ToString();
                    }
                    else
                    {
                        cErr = $"单据号{obj.cVouchID}不存在";
                    }
                    
                    
                }
                List<AP_Vouch.Body> bodies = new List<AP_Vouch.Body>();

                APVouchVM model = new APVouchVM(head, bodies);

                return model;

            }
            catch (Exception ex)
            {
                cErr = ex.Message;
                return null;
            }





        }

        /// <summary>
        /// 检查单号是否存在
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Exists(ref string id)
        {
            if (head == null)
            {
                return false;
            }

            using (SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = conStr,
                DbType = SqlSugar.DbType.SqlServer,
                IsAutoCloseConnection = true
            }))
            {
                string sql = string.Format("select clink from AP_ApVouch where cVouchID='{0}' ", head.cVouchID);
                id = DbHelper.GetDbString(db.Ado.GetScalar(sql));


                if (id == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }

            }

        }
    }
}
